/*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2012 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author:                                                              |
  +----------------------------------------------------------------------+
*/

/* $Id$ */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_tair.h"
#include <zend_exceptions.h>

/* If you declare any globals in php_tair.h uncomment this:
ZEND_DECLARE_MODULE_GLOBALS(tair)
*/
#include <ext/standard/php_smart_str.h>
#include <ext/standard/php_var.h>
#include <ext/standard/php_math.h>

/* True global resources - no need for thread safety here */
static int le_tair;

/* {{{ tair_functions[]
 *


 * Every user visible function must have an entry in tair_functions[].
 */
 
 zend_class_entry *tair_ce;
zend_class_entry *tair_exception_ce;
zend_class_entry *spl_ce_RuntimeException = NULL;
PHP_INI_BEGIN()
	/* tair arrays */
	PHP_INI_ENTRY("tair.arrays.names", "", PHP_INI_ALL, NULL)
	PHP_INI_ENTRY("tair.arrays.hosts", "", PHP_INI_ALL, NULL)
	PHP_INI_ENTRY("tair.arrays.previous", "", PHP_INI_ALL, NULL)
	PHP_INI_ENTRY("tair.arrays.functions", "", PHP_INI_ALL, NULL)
	PHP_INI_ENTRY("tair.arrays.index", "", PHP_INI_ALL, NULL)
	PHP_INI_ENTRY("tair.arrays.autorehash", "", PHP_INI_ALL, NULL)
PHP_INI_END()
//ZEND_DECLARE_MODULE_GLOBALS(tair)
static zend_function_entry tair_functions[] = {
     PHP_ME(Tair, __construct, NULL, ZEND_ACC_PUBLIC)
     PHP_ME(Tair, __destruct, NULL, ZEND_ACC_PUBLIC)
     PHP_ME(Tair, connect, NULL, ZEND_ACC_PUBLIC)
     PHP_ME(Tair, close, NULL, ZEND_ACC_PUBLIC)
     PHP_ME(Tair, get, NULL, ZEND_ACC_PUBLIC)
     PHP_ME(Tair, set, NULL, ZEND_ACC_PUBLIC)
     {NULL, NULL, NULL}
};
/* }}} */

/* {{{ tair_module_entry
 */
zend_module_entry tair_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
	STANDARD_MODULE_HEADER,
#endif
	"tair",
     NULL,
	PHP_MINIT(tair),
	PHP_MSHUTDOWN(tair),
	PHP_RINIT(tair),		/* Replace with NULL if there's nothing to do at request start */
	PHP_RSHUTDOWN(tair),	/* Replace with NULL if there's nothing to do at request end */
	PHP_MINFO(tair),
#if ZEND_MODULE_API_NO >= 20010901
	PHP_TAIR_VERSION, /* Replace with version number for your extension */
#endif
	STANDARD_MODULE_PROPERTIES
};
/* }}} */

#ifdef COMPILE_DL_TAIR
ZEND_GET_MODULE(tair)
#endif

PHPAPI zend_class_entry *tair_get_exception_base(int root TSRMLS_DC)
{
#if HAVE_SPL
        if (!root) {
                if (!spl_ce_RuntimeException) {
                        zend_class_entry **pce;
                        if (zend_hash_find(CG(class_table), "runtimeexception",
                                                           sizeof("RuntimeException"), (void **) &pce) == SUCCESS) {
                                spl_ce_RuntimeException = *pce;
                                return *pce;
                        }
                } else {
                        return spl_ce_RuntimeException;
                }
        }
#endif
#if (PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 2)
        return zend_exception_get_default();
#else
        return zend_exception_get_default(TSRMLS_C);
#endif
}

/* Remove comments and fill if you need to have entries in php.ini
PHP_INI_BEGIN()
    STD_PHP_INI_ENTRY("tair.global_value",      "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_tair_globals, tair_globals)
    STD_PHP_INI_ENTRY("tair.global_string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_tair_globals, tair_globals)
PHP_INI_END()
*/
/* }}} */

/* {{{ php_tair_init_globals
 */
/* Uncomment this function if you have INI entries 
static void php_tair_init_globals(zend_tair_globals *tair_globals)
{
	tair_globals->global_value = 0;
	tair_globals->global_string = NULL;
}
*/
/* }}} */

/* {{{ PHP_MINIT_FUNCTION
 */
PHP_MINIT_FUNCTION(tair)
{
    zend_class_entry tair_class_entry;
    zend_class_entry tair_array_class_entry;
    zend_class_entry tair_exception_class_entry;

	REGISTER_INI_ENTRIES();
	INIT_CLASS_ENTRY(tair_class_entry, "Tair", tair_functions);
    tair_ce = zend_register_internal_class(&tair_class_entry TSRMLS_CC);

    INIT_CLASS_ENTRY(tair_exception_class_entry, "TairException", NULL);
    tair_exception_ce = zend_register_internal_class_ex(
        &tair_exception_class_entry,
        tair_get_exception_base(0 TSRMLS_CC),
        NULL TSRMLS_CC
    );
	zend_declare_class_constant_stringl(tair_ce, "AFTER", 5, "after", 5 TSRMLS_CC);
	zend_declare_class_constant_stringl(tair_ce, "BEFORE", 6, "before", 6 TSRMLS_CC);
	return SUCCESS;
}
/* }}} */

/* {{{ PHP_MSHUTDOWN_FUNCTION
 */
PHP_MSHUTDOWN_FUNCTION(tair)
{
	/* uncomment this line if you have INI entries
	UNREGISTER_INI_ENTRIES();
	*/
	return SUCCESS;
}
/* }}} */

/* Remove if there's nothing to do at request start */
/* {{{ PHP_RINIT_FUNCTION
 */
PHP_RINIT_FUNCTION(tair)
{
	return SUCCESS;
}
/* }}} */

/* Remove if there's nothing to do at request end */
/* {{{ PHP_RSHUTDOWN_FUNCTION
 */
PHP_RSHUTDOWN_FUNCTION(tair)
{
	return SUCCESS;
}
/* }}} */

/* {{{ PHP_MINFO_FUNCTION
 */
PHP_MINFO_FUNCTION(tair)
{
	php_info_print_table_start();
    php_info_print_table_header(2, "Tair Support", "enabled");
    php_info_print_table_row(2, "Tair Version", PHP_TAIR_VERSION);
	php_info_print_table_end();
}
/* {{{ proto Tair Tair::__construct()
    Public constructor */
PHP_METHOD(Tair, __construct)
{
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) {
        RETURN_FALSE;
    }
}
/* }}} */

/* {{{ proto Tair Tair::__destruct()
    Public Destructor
 */
PHP_METHOD(Tair,__destruct) {
	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) {
		RETURN_FALSE;
	}
}

PHPAPI int tair_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) {
	zval *object;
	zval **socket;
	int host_len, id;
	char *host = NULL;
	long port = -1;

	char *persistent_id = NULL;
	int persistent_id_len = -1;
	double timeout = 0.0;
	//TairSock *tair_sock  = NULL;
#ifdef ZTS
	/* not sure how in threaded mode this works so disabled persistents at first */
    persistent = 0;
#endif

	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|lds",
				&object, tair_ce, &host, &host_len, &port,
				&timeout, &persistent_id, &persistent_id_len) == FAILURE) {
		return FAILURE;
	}
	if (timeout < 0L || timeout > INT_MAX) {
		zend_throw_exception(tair_exception_ce, "Invalid timeout", 0 TSRMLS_CC);
		return FAILURE;
	}
	if(port == -1 && host_len && host[0] != '/') { /* not unix socket, set to default value */
		port = 80;
	}


	add_property_resource(object, "socket", id);

	return SUCCESS;
}

/* {{{ proto boolean Tair::connect(string host, int port [, double timeout])
 */
PHP_METHOD(Tair, connect) {
	if (tair_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0) == FAILURE) {
		RETURN_FALSE;
	} else {
		RETURN_TRUE;
	}
}
/* }}} */


/* {{{ proto boolean Tair::set(string key, mixed value)
 */
PHP_METHOD(Tair, set) {
    zval *object;
    //RedisSock *redis_sock;
    char *key = NULL, *val = NULL, *cmd;
    int key_len, val_len, cmd_len;
    long expire = -1;
    int val_free = 0, key_free = 0;
    zval *z_value;

    if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osz|l",
                                     &object, tair_ce, &key, &key_len,
                                     &z_value, &expire) == FAILURE) {
        RETURN_FALSE;
    }
	RETURN_FALSE;
}



/* {{{ proto string Tair::get(string key)
 */
PHP_METHOD(Tair, get) {
    zval *object;
    char *key = NULL, *cmd;
    int key_len, cmd_len;
	int key_free;

    if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os",
                                     &object, tair_ce,
                                     &key, &key_len) == FAILURE) {
        RETURN_FALSE;
    }
	RETURN_FALSE;

}
/* }}} */


/* {{{ proto boolean Tair::close()
 */
PHP_METHOD(Tair, close) {
    zval *object;

    if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
        &object, tair_ce) == FAILURE) {
        RETURN_FALSE;
    }

    RETURN_FALSE;
}
/* }}} */



/* The previous line is meant for vim and emacs, so it can correctly fold and 
   unfold functions in source code. See the corresponding marks just before 
   function definition, where the functions purpose is also documented. Please 
   follow this convention for the convenience of others editing your code.
*/


/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
